/* jowles-app.c
**
** Copyright (c) 2007, Homebrew Mobile Phone Club
** All rights reserved.
** 
** Redistribution  and  use  in  source  and  binary  forms,  with  or  without
** modification, are permitted provided that the following conditions are met:
** 
**  * Redistributions of  source code must  retain the above  copyright notice,
**    this list of conditions and the following disclaimer.
** 
**  * Redistributions in binary form must reproduce the above copyright notice,
**    this list of conditions and the following disclaimer in the documentation
**    and/or other materials provided with the distribution.
** 
**  * Neither the name  of the Homebrew Mobile Phone Club nor  the names of its
**    contributors may be used to endorse or promote products derived from this
**    software without specific prior written permission.
** 
** THIS SOFTWARE IS PROVIDED BY  THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY  EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT  LIMITED TO, THE
** IMPLIED WARRANTIES  OF MERCHANTABILITY AND FITNESS FOR  A PARTICULAR PURPOSE
** ARE DISCLAIMED.  IN NO  EVENT SHALL THE  COPYRIGHT OWNER OR  CONTRIBUTORS BE
** LIABLE  FOR  ANY  DIRECT,   INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
** CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
** SUBSTITUTE GOODS  OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
** INTERRUPTION)  HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN
** CONTRACT,  STRICT LIABILITY,  OR  TORT (INCLUDING  NEGLIGENCE OR  OTHERWISE)
** ARISING IN ANY WAY  OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** 
** $Id: jowles-app.c 4 2007-11-04 18:52:39Z msh.mobile $
*/

/* Macro Definitions */

/* File Includes */
#include "jowles/jowles-app.h"
#include "glib.h"
#include <stdlib.h>

/* Typedefs, Structs, Unions, Enums, etc. */

/* Static Function Prototypes */
static GObject *jowles_app_constructor( GType type, guint n_construct_properties, GObjectConstructParam *construct_properties);
static void jowles_app_class_init (gpointer g_class, gpointer g_class_data);
static void jowles_app_instance_init( GTypeInstance *i, gpointer g_class );
void jowles_app_init( JowlesApp *self, int argc, char **argv );
void jowles_app_usage( JowlesApp *self );
static void jowles_app_default_run( JowlesApp *self );

/* Variable Declarations */
extern GType (*jowles_app_object_type)( void );
extern const gchar *jowles_app_parameter_name;
extern const gchar *jowles_app_default_name;
extern const gchar *jowles_app_default_interface;

static GObjectClass *parent_class = NULL;

/* Function Definitions */

int main( int argc, char *argv[] ) {
  RErr err = JOWLES_E_NOERR;
  GObject *bar = NULL;

  do {
    g_type_init();

    if( NULL == ( bar = g_object_new( jowles_app_object_type(), NULL ) ) ) {
      break;
    }

    jowles_app_init( JOWLES_APP( bar ), argc, argv );

    jowles_app_run( JOWLES_APP( bar ) );
  } while( 0 );

  switch( err ) {
  case JOWLES_E_USAGE:
    jowles_app_usage( JOWLES_APP( bar ) );
    break;
  }

  if( NULL != bar ) {
    g_object_unref( G_OBJECT( bar ) );
  }

  return( RErr_As_8Bit_Int( err ) );
}

static GObject *jowles_app_constructor( GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) {
  GObject *obj;

  /* Invoke parent constructor. */
  JowlesAppClass *klass;
  klass = JOWLES_APP_CLASS (g_type_class_peek (JOWLES_TYPE_APP));
  obj = parent_class->constructor (type, n_construct_properties, construct_properties);
        
  return( obj );
}

static void jowles_app_class_init (gpointer g_class, gpointer g_class_data) {
  JowlesAppClass *klass = JOWLES_APP_CLASS (g_class);
  parent_class = g_type_class_peek_parent (klass);
  klass->run = jowles_app_default_run;
}

static void jowles_app_instance_init( GTypeInstance *i, gpointer g_class ) {
  JowlesApp *self = (JowlesApp *)i;

  self->name = NULL;
  self->interface = NULL;
  self->conf_interface = NULL;
}

GType jowles_app_get_type( ) {
  static GType type = 0;
  static const GTypeInfo info = {
    sizeof (JowlesAppClass),
    NULL,                     /* base_init */
    NULL,                     /* base_finalize */
    jowles_app_class_init,    /* class_init */
    NULL,                     /* class_finalize */
    NULL,                     /* class_data */
    sizeof (JowlesApp),
    0,                        /* n_preallocs */
    jowles_app_instance_init  /* instance_init */
  };
  
  if( 0 == type ) {
    type = g_type_register_static (G_TYPE_OBJECT, "JowlesAppType", &info, 0);
  }
  
  return( type );
}

void jowles_app_init( JowlesApp *self, int argc, char **argv ) {
  GError *error;
  GOptionContext *context;
  static gchar *interface = NULL;
  static gchar *conf_interface = NULL;
  static gchar *name = NULL;
  static GOptionEntry entries[] = {
    { "name", 'n', 0, G_OPTION_ARG_STRING, &name, "application name", NULL },
    { "interface", 'i', 0, G_OPTION_ARG_STRING, &interface, "interface to export", NULL },
    { "config", 'c', 0, G_OPTION_ARG_STRING, &conf_interface, "configuration interface to use", NULL },
    { NULL }
  };

  JOWLES_LOG( JOWLES_LOG_CALLS, "Entering jowles_app_init()" );

  error = NULL;

  /* Initialize App Members */
  self->name           = NULL;
  self->interface      = NULL;
  self->conf_interface = NULL;
  self->connection     = NULL;

  /* Parse Command Line */

  context = g_option_context_new( jowles_app_parameter_name );
  g_option_context_add_main_entries( context, entries, NULL );
  g_option_context_parse( context, &argc, &argv, &error );

  if( NULL != name ) { self->name = name; }
  if( NULL != interface ) { self->interface = interface; }
  if( NULL != conf_interface ) { self->conf_interface = conf_interface; }

  /* Open Connection with configuration service and retreive values */
  self->connection = dbus_g_bus_get( DBUS_BUS_SESSION, &error );
  if( NULL == self->connection) {
    g_printerr("failed to open connection to session bus: %s\n", error->message );
    g_error_free( error );
    exit( 1 );
  }

  self->proxy = dbus_g_proxy_new_for_name( self->connection, DBUS_SERVICE_DBUS,
					   DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS );


  /* Insert Defaults */
  if( NULL == self->name ) { self->name = (gchar *) jowles_app_default_name ; }
  if( NULL == self->interface ) { self->interface = (gchar *) jowles_app_default_interface ; }
  if( NULL == self->conf_interface ) { self->conf_interface = "org.hbmobile.jowles.rConf"; }

  g_print( "name is %s\n", self->name );
  g_print( "interface is %s\n", self->interface );
  g_print( "config interface is %s\n", self->conf_interface );

  JOWLES_LOG( JOWLES_LOG_CALLS, "Exiting jowles_app_init()" ); 
}

void jowles_app_run( JowlesApp *self ) {
  g_print( "jowles_app_run()\n");
 
  (JOWLES_APP_GET_CLASS( self ))->run( self );
}

void jowles_app_usage( JowlesApp *self ) {
  g_print( "jowles_app_usage()\n");
}

static void jowles_app_default_run( JowlesApp *self ) {
  g_print( "jowles_app_default_run()\n");
}
